home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
source
/
demostuf
/
magnify2.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-07-25
|
6KB
|
290 lines
program magnify;
{
Magnify #2
... now: on a tweak-vga screen with a larger glass!
- by Bjarke Viksφe
mar 1994
THIS PROGRAM WAS CODED BY BJARKE VIKS0E.
YOU ARE FREE TO DO WHATEVER YOU WANT WITH THIS PIECE OF CODE.
E-MAIL ME AT: dat92230@rix02.lyngbyes.dk IN 1994 FOR CHAT AND CODE.
This time true DPMI. No more self-modifying cheating.
It looks allright - and takes only half a screen on my machine, but
doing 7414 plots in a row... pheew!
The formula is still not quite right. It's only bending the pix around
the glass... but who cares?
How does it work. Well, a simple math.formula bends pixels from a
square and puts the result in an array.
So we tranverse the square from (x1,y1) to (x2,y1) through (x2,y2).
We put our x/y values through the math.formula and the resulting
coords are used as index to store the address-offset that our square
x/y point to.
We could now go through the array. If the index has a value then
we use the value as an offset into our graphics. We then get the
colour value and plot the pixel. Else if the index has no value simply
skip plotting any pixel at this point.
But the big array is compacted so that no non-value indexes are
left. A lot quicker. And the again we split the new
array into 4 arrays to speed things up when writing to the tweaked-screen.
}
uses
DEMOINIT,ILBM256;
const
DEBUG = FALSE;
MAX = 48;
type
pPosBuffer = ^PosBufferType;
PosBufferType = array[0..1500*2] of word;
var
stackseg,stackptr : word;
oldx,oldy : integer;
xpos, ypos, xadd, yadd : word;
xpostabel : array [0..511] of integer;
ypostabel : array [0..511] of integer;
posbuffer: array[0..3] of pPosBuffer;
posantal : array[0..3] of integer;
ztabel : array [0..MAX*2] of integer;
screen,tempscreen : pScreen;
const
display1 : integer = $0000;
display2 : integer = $4000;
(*------------------------------------------------*)
procedure SetupSinus;
var
i : integer;
v, vadd : real;
begin
v:=0.0;
vadd:=(2.0*pi/512.0);
for i:=0 to 511 do begin
xpostabel[i]:=round(sin(v)*110)+160;
v:=v+vadd;
end;
v:=0.0;
vadd:=(2.0*pi/512.0);
for i:=0 to 511 do begin
ypostabel[i]:=round(sin(v)*50)+100;
v:=v+vadd;
end;
v:=pi/2.0;
vadd:=(pi/2.0)/(MAX*2.0);
for i:=0 to MAX*2 do begin
ztabel[i]:=round(sin(v)*2500);
v:=v+vadd;
end;
end;
procedure CalcMatrix;
type
matrice = array[-MAX..MAX-1, -MAX..MAX-1] of word;
var
i,j : integer;
x,y,z : longint;
tx,ty : longint;
matrix : ^matrice;
begin
New(matrix);
FillChar(matrix^,SIZEOF(matrice),0);
for y:=-MAX to MAX-1 do
for x:=-MAX to MAX-1 do begin
z := round(sqrt(sqr(x)+sqr(y)));
z := ztabel[z];
tx := (x*z) DIV 2170; {... use different values because of}
ty := (y*z) DIV 2300; {different scaling of x/y axis}
{ the next if-sentence is to handle that strange bend when data
is put into buffer in wrong order? }
if (tx=x) AND (ty=y) then continue;
if (y<=0) then matrix^[tx,ty] := longmul(y,320)+(x)
else if (matrix^[tx,ty]=0) then matrix^[tx,ty] := longmul(y,320)+(x);
end;
posantal[0]:=0;
posantal[1]:=0;
posantal[2]:=0;
posantal[3]:=0;
for y:=-MAX to MAX-1 do
for x:=-MAX to MAX-1 do
if (matrix^[x,y]<>0) then begin
j:=x AND 3;
i:=posantal[j];
posbuffer[j]^[i]:=longmul(y,WIDTH)+(x shr 2);
posbuffer[j]^[i+1]:=matrix^[x,y];
inc(posantal[j],2);
end;
Dispose(matrix);
end;
procedure InitDemo;
var
i : integer;
begin
FadeCMAP(0);
ClearWholeScreen;
SetupSinus;
for i:=0 to 3 do new(posbuffer[i]);
CalcMatrix;
xpos :=40; ypos:=20;
oldx:=160; oldy:=100;
xadd :=2; yadd:=1;
New(screen);
New(tempscreen);
LoadPix(screen,'parasit1.lbm');
MakeTweak(screen,tempscreen);
Copy2TweakScreen(tempscreen,Ptr(SEGA000,display1));
Copy2TweakScreen(tempscreen,Ptr(SEGA000,display2));
for i:=0 to 64 do FadeCMAP(i*4);
end;
procedure UninitDemo;
var
i : integer;
begin
for i:=0 to 3 do Dispose(posbuffer[i]);
Dispose(screen);
Dispose(tempscreen);
end;
(*------------------------------------------------*)
procedure SwapDisplay;
var
temp : word;
begin
temp:=display2;
display2:=display1;
display1:=temp;
SetAddress(Ptr(SEGA000,display2));
end;
(*------------------------------------------------*)
procedure CopyFromBuffer(x,y : integer);
var
i : integer;
source_offset, dest_offset : word;
begin
dec(x,MAX);
dec(y,MAX);
source_offset:=longmul(y,WIDTH)+((x shr 3) shl 1);
dest_offset:=source_offset;
for i:=0 to 3 do begin
SetBitplanes(1 shl i);
asm
push ds
mov es,SEGA000
mov di,display1
lds si,tempscreen
add si,source_offset
add di,dest_offset
mov bx,WIDTH-(MAX/2)
mov cx,MAX*2
cld
@yloop: mov dx,cx
mov cx,MAX/8
DB $F3,$66,$A5 {rep stosd}
add si,bx
add di,bx
mov cx,dx
loop @yloop
pop ds
end;
inc(source_offset,80*200);
end;
end;
procedure PrintMagnifyGlass(src_offset, dst_offset : integer; p : pPosBuffer;
antal : integer); assembler;
asm
mov stackptr,bp
mov es,SEGA000
mov ax,WORD PTR screen+2
mov dx,src_offset
lds si,p
mov cx,antal
mov bp,dst_offset
shr cx,1
DB $8E,$E0 {mov fs,ax}
cld
@loop:
lodsw
add ax,bp
mov di,ax
lodsw
add ax,dx
mov bx,ax
DB $64 {FS: prefix}
mov al,[bx]
mov [es:di],al
loop @loop
mov ax,SEG @DATA
mov ds,ax
mov bp,stackptr
end;
(*------------------------------------------------*)
procedure RunOnce;
var
i : integer;
x,y : integer;
src_offs, dst_offs : integer;
begin
SwapDisplay;
VBLANK;
if DEBUG then SetRGB(0,30,0,0);
CopyFromBuffer(oldx,oldy);
x := xpostabel[xpos AND 511];
y := ypostabel[ypos AND 511];
src_offs:=longmul(y,320)+x;
dst_offs:=(longmul(y,WIDTH)+(x shr 2))+display1;
for i:=0 to 3 do begin
SetBitplanes(1 shl (x AND 3));
PrintMagnifyGlass(src_offs,dst_offs, posbuffer[i],posantal[i]);
if ((x AND 3) = 3) then inc(dst_offs);
inc(x);
end;
oldx:=x; oldy:=y;
inc(xpos,xadd);
inc(ypos,yadd);
if DEBUG then SetRGB(0,0,0,0);
end;
begin
OpenScreen;
Screen_Off;
InitDemo;
Screen_On;
repeat RunOnce until KeyPressed;
UninitDemo;
CloseScreen;
end.